#include "stdafx.h"
#include "net/HTTPServerRequestImpl.hpp"
#include "net/HTTPServerResponseImpl.hpp"
#include "net/HTTPHeaderStream.hpp"
#include "net/HTTPChunkedStream.hpp"
#include "net/HTTPFixedLengthStream.hpp"
#include "net/HTTPStream.hpp"

NET_NAMESPACE_BEGIN

const std::string CHTTPServerRequestImpl::EXPECT("Expect");

CHTTPServerRequestImpl::CHTTPServerRequestImpl(CHTTPServerResponseImpl& response, CHTTPServerSession& session, CHTTPServerParams* pParams)
	: m_response(response),
	m_session(session),
	m_pStream(0),
	m_pParams(pParams, true)
{
	response.attachRequest(this);

	CHTTPHeaderInputStream hs(session);
	read(hs);

	// Now that we know socket is still connected, obtain addresses
	m_clientAddress = session.clientAddress();
	m_serverAddress = session.serverAddress();

	if (getChunkedTransferEncoding())
		m_pStream = new CHTTPChunkedInputStream(session);
	else if (hasContentLength())
#if defined(JH_HAVE_INT64)
		m_pStream = new CHTTPFixedLengthInputStream(session, getContentLength64());
#else
		m_pStream = new CHTTPFixedLengthInputStream(session, getContentLength());
#endif
	else if (getMethod() == CHTTPRequest::HTTP_GET || getMethod() == CHTTPRequest::HTTP_HEAD)
		m_pStream = new CHTTPFixedLengthInputStream(session, 0);
	else
		m_pStream = new CHTTPInputStream(session);
}

CHTTPServerRequestImpl::~CHTTPServerRequestImpl()
{
	delete m_pStream;
}

CStreamSocket& CHTTPServerRequestImpl::socket()
{
	return m_session.socket();
}

CStreamSocket CHTTPServerRequestImpl::detachSocket()
{
	return m_session.detachSocket();
}

bool CHTTPServerRequestImpl::expectContinue() const
{
	const std::string& expect = get(EXPECT, EMPTY);
	return !expect.empty() && icompare(expect, "100-continue") == 0;
}

std::istream& CHTTPServerRequestImpl::stream()
{
	jh_check_ptr (m_pStream);

	return *m_pStream;
}

const CSocketAddress& CHTTPServerRequestImpl::clientAddress() const
{
	return m_clientAddress;
}

const CSocketAddress& CHTTPServerRequestImpl::serverAddress() const
{
	return m_serverAddress;
}

const CHTTPServerParams& CHTTPServerRequestImpl::serverParams() const
{
	return *m_pParams;
}

CHTTPServerResponse& CHTTPServerRequestImpl::response() const
{
	return m_response;
}

NET_NAMESPACE_END
